package com.lzy.mall.product.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.lzy.mall.common.constant.Constant;
import com.lzy.mall.common.utils.PageUtils;
import com.lzy.mall.product.dao.PmsAttrAttrgroupRelationDao;
import com.lzy.mall.product.dao.PmsAttrGroupDao;
import com.lzy.mall.product.dao.PmsCategoryDao;
import com.lzy.mall.product.entity.PmsAttr;
import com.lzy.mall.product.dao.PmsAttrDao;
import com.lzy.mall.product.entity.PmsAttrAttrgroupRelation;
import com.lzy.mall.product.entity.PmsAttrGroup;
import com.lzy.mall.product.entity.PmsCategory;
import com.lzy.mall.product.service.PmsAttrService;
import com.lzy.mall.product.service.PmsCategoryService;
import com.lzy.mall.common.utils.PageParaUtils;
import com.lzy.mall.product.domain.PmsEnum;
import com.lzy.mall.product.vo.AttrGroupRelationVo;
import com.lzy.mall.product.vo.AttrRespVo;
import com.lzy.mall.product.vo.PmsAttrVO;
import org.beetl.sql.core.engine.PageQuery;
import org.springframework.stereotype.Service;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * 商品属性(PmsAttr)表服务实现类
 *
 * @author lzy
 * @since 2021-08-25 11:41:06
 */
@Service
@RequiredArgsConstructor(onConstructor_ = {@Autowired})
public class PmsAttrServiceImpl implements PmsAttrService {
    private final PmsAttrDao pmsAttrDao;

    private final PmsAttrAttrgroupRelationDao relationDao;

    private final PmsAttrGroupDao groupDao;

    private final PmsCategoryService categoryService;

    private final PmsCategoryDao categoryDao;

    @Override
    @Transactional
    public void saveAttr(PmsAttrVO attrVO) {
        PmsAttr pmsAttr = new PmsAttr();
        BeanUtil.copyProperties(attrVO,pmsAttr);

        pmsAttrDao.insertTemplate(pmsAttr,true);
        if (PmsEnum.ATTR_TYPE_BASE.getCode().equals(attrVO.getAttrType()) && ObjectUtil.isNotNull(attrVO.getCatelogId())){
            PmsAttrAttrgroupRelation build = PmsAttrAttrgroupRelation.builder()
                    .attrId(pmsAttr.getAttrId())
                    .attrGroupId(attrVO.getAttrGroupId())
                    .attrSort(0)
                    .build();
            relationDao.insertTemplate(build);
        }
    }

    @Override
    public PageUtils queryBaseAttrPage(Map<String, Object> params, Long catelogId, String type) {
        PageQuery pageQuery = PageParaUtils.pagePara(params);
        Integer t = Constant.ATTR_TYPE_BASE.equalsIgnoreCase(type)?1:0;
        pageQuery.setPara("type",t);
        if (ObjectUtil.isNotNull(catelogId) && !Constant.ALL_LIST_CAT_ID.equals(catelogId)){
            pageQuery.setPara("id",catelogId);
        }
        PageQuery<AttrRespVo> page = pmsAttrDao.queryBaseAttrPage(pageQuery);
        List<AttrRespVo> list = page.getList();
        list.forEach(a -> {
            Long[] catelogPath = categoryService.findCatelogPath(a.getCatelogId());
            a.setCatelogPath(catelogPath);
        });
        page.setList(list);
        return new PageUtils(page);
    }

    @Override
    public AttrRespVo getAttrInfo(Long attrId) {
        PmsAttr single = pmsAttrDao.single(attrId);
        AttrRespVo vo = new AttrRespVo();
        BeanUtil.copyProperties(single,vo);

        PmsCategory category = categoryDao.single(single.getCatelogId());
        PmsAttrAttrgroupRelation select = relationDao.createLambdaQuery()
                .andEq(PmsAttrAttrgroupRelation::getAttrId, attrId)
                .single();

        Long[] catelogPath = categoryService.findCatelogPath(single.getCatelogId());

        if (!PmsEnum.ATTR_TYPE_BASE.getCode().equals(single.getAttrType())){
            PmsAttrGroup group = groupDao.createLambdaQuery()
                    .andEq(PmsAttrGroup::getAttrGroupId, select.getAttrGroupId())
                    .single();
            vo.setAttrGroupId(group.getAttrGroupId());
            vo.setGroupName(group.getAttrGroupName());
        }
        vo.setCatelogPath(catelogPath);
        vo.setCatelogName(category.getName());

        return vo;
    }

    @Override
    @Transactional
    public void updateAttr(PmsAttrVO attr) {
        PmsAttr a = new PmsAttr();
        BeanUtil.copyProperties(attr,a);
        pmsAttrDao.updateTemplateById(a);

        PmsAttrAttrgroupRelation relation = relationDao.createLambdaQuery()
                .andEq(PmsAttrAttrgroupRelation::getAttrId, attr.getAttrId())
                .single();
        relation.setAttrGroupId(attr.getAttrGroupId());
        if (ObjectUtil.isNotNull(relation)){
            relationDao.updateTemplateById(relation);
        }else {
            relation.setAttrId(attr.getAttrId());
            relationDao.insertTemplate(relation);
        }


    }

    @Override
    public void removeByIds(List<Long> ids) {
        pmsAttrDao.createLambdaQuery()
                .andIn(PmsAttr::getAttrId,ids)
                .delete();
    }

    @Override
    public List<PmsAttr> getRelationAttr(Long attrgroupId) {
        List<PmsAttrAttrgroupRelation> select = relationDao.createLambdaQuery()
                .andEq(PmsAttrAttrgroupRelation::getAttrGroupId, attrgroupId)
                .select();
        List<Long> attrIds = select.stream().map(PmsAttrAttrgroupRelation::getAttrId).collect(Collectors.toList());

        if (CollUtil.isEmpty(attrIds)){
            return null;
        }
        List<PmsAttr> attrs = pmsAttrDao.createLambdaQuery()
                .andIn(PmsAttr::getAttrId, attrIds)
                .select();
        return attrs;
    }

    /**
     * 获取当前分组没有关联的所有属性
     * @param params
     * @param attrgroupId
     * @return
     */
    @Override
    public PageUtils getNoRelationAttr(Map<String, Object> params, Long attrgroupId) {
        //1.当前分组只能关联所属分类里的所有属性
        PmsAttrGroup attrGroup = groupDao.single(attrgroupId);
        Long catelogId = attrGroup.getCatelogId();

        List<Long> attrIds = relationDao.createLambdaQuery()
                .andEq(PmsAttrAttrgroupRelation::getAttrGroupId, attrgroupId)
                .select()
                .stream()
                .map(PmsAttrAttrgroupRelation::getAttrId)
                .collect(Collectors.toList());

        PageQuery pageQuery = PageParaUtils.pagePara(params);
        pageQuery.setPara("id",catelogId);
        pageQuery.setPara("type",attrGroup.getType());
        PageQuery<PmsAttr> page = pmsAttrDao.getNoRelationAttr(pageQuery);

        if (CollUtil.isNotEmpty(attrIds)){
            List<PmsAttr> list = page.getList();
            List<PmsAttr> collect = list.stream().filter(pmsAttr -> !attrIds.contains(pmsAttr.getAttrId())).collect(Collectors.toList());
            page.setList(collect);
        }

        return new PageUtils(page);
    }

    @Override
    public void deleteRelation(AttrGroupRelationVo[] vos) {
        ArrayList<AttrGroupRelationVo> list = CollUtil.toList(vos);
        list.forEach(a -> {
            relationDao.createLambdaQuery()
                    .andEq(PmsAttrAttrgroupRelation::getAttrGroupId,a.getAttrGroupId())
                    .andEq(PmsAttrAttrgroupRelation::getAttrId,a.getAttrId())
                    .delete();
        });
    }

    @Override
    public PmsAttr getById(Long attrId) {
        return pmsAttrDao.single(attrId);
    }

    @Override
    public List<Long> searchAttrIds(List<Long> attrIds) {
        List<Long> list = pmsAttrDao.createLambdaQuery()
                .andIn(PmsAttr::getAttrId, attrIds)
                .andEq(PmsAttr::getAttrType, Constant.ATTR_IS_SEARCH)
                .select()
                .stream()
                .map(PmsAttr::getAttrId)
                .collect(Collectors.toList());
        return list;
    }
}
